use std::collections::HashMap;
use tree_sitter::{Parser, Tree, Node, Query, QueryCursor};
use anyhow::{anyhow, Result};

/// DPML解析器
pub struct DpmlParser {
    parser: Parser,
    query_cache: HashMap<String, Query>,
}

impl DpmlParser {
    /// 创建新的DPML解析器
    pub fn new() -> Result<Self> {
        let mut parser = Parser::new();
        parser.set_language(tree_sitter_dpml::language())
            .map_err(|e| anyhow!("Failed to set DPML language: {}", e))?;
        
        Ok(Self {
            parser,
            query_cache: HashMap::new(),
        })
    }

    /// 解析DPML文档
    pub fn parse(&mut self, source: &str) -> Result<DpmlDocument> {
        let tree = self.parser.parse(source, None)
            .ok_or_else(|| anyhow!("Failed to parse DPML document"))?;
        
        DpmlDocument::from_tree(tree, source)
    }

    /// 执行查询
    pub fn query(&mut self, source: &str, query_str: &str) -> Result<usize> {
        let tree = self.parser.parse(source, None)
            .ok_or_else(|| anyhow!("Failed to parse DPML document"))?;

        let query = if self.query_cache.contains_key(query_str) {
            // 从缓存获取查询
            self.query_cache.get(query_str).unwrap()
        } else {
            // 创建新查询并缓存
            let new_query = Query::new(tree_sitter_dpml::language(), query_str)
                .map_err(|e| anyhow!("Invalid query: {}", e))?;
            self.query_cache.insert(query_str.to_string(), new_query);
            self.query_cache.get(query_str).unwrap()
        };

        let mut cursor = QueryCursor::new();
        let match_count = cursor.matches(query, tree.root_node(), source.as_bytes())
            .count();

        Ok(match_count)
    }
}

impl Default for DpmlParser {
    fn default() -> Self {
        Self::new().expect("Failed to create DPML parser")
    }
}

/// DPML文档表示
#[derive(Debug, Clone)]
pub struct DpmlDocument {
    tree: Tree,
    source: String,
}

impl DpmlDocument {
    /// 从tree-sitter树创建DPML文档
    pub fn from_tree(tree: Tree, source: &str) -> Result<Self> {
        Ok(Self {
            tree,
            source: source.to_string(),
        })
    }

    /// 获取根节点
    pub fn root(&self) -> DpmlNode {
        DpmlNode::new(self.tree.root_node(), &self.source)
    }

    /// 获取所有元素
    pub fn elements(&self) -> Vec<DpmlElement> {
        let mut elements = Vec::new();
        self.collect_elements(self.tree.root_node(), &mut elements);
        elements
    }

    /// 递归收集所有元素
    fn collect_elements(&self, node: Node, elements: &mut Vec<DpmlElement>) {
        if node.kind() == "element" {
            if let Ok(element) = DpmlElement::from_node(node, &self.source) {
                elements.push(element);
            }
        }
        
        for child in node.children(&mut node.walk()) {
            self.collect_elements(child, elements);
        }
    }

    /// 查找指定标签名的元素
    pub fn find_elements_by_tag(&self, tag_name: &str) -> Vec<DpmlElement> {
        self.elements()
            .into_iter()
            .filter(|e| e.tag_name() == tag_name)
            .collect()
    }

    /// 获取所有资源引用
    pub fn resource_references(&self) -> Vec<ResourceReference> {
        let mut references = Vec::new();
        self.collect_resource_references(self.tree.root_node(), &mut references);
        references
    }

    /// 递归收集资源引用
    fn collect_resource_references(&self, node: Node, references: &mut Vec<ResourceReference>) {
        if node.kind() == "resource_reference" {
            if let Ok(reference) = ResourceReference::from_node(node, &self.source) {
                references.push(reference);
            }
        }
        
        for child in node.children(&mut node.walk()) {
            self.collect_resource_references(child, references);
        }
    }

    /// 获取所有术语引用
    pub fn term_references(&self) -> Vec<TermReference> {
        let mut references = Vec::new();
        self.collect_term_references(self.tree.root_node(), &mut references);
        references
    }

    /// 递归收集术语引用
    fn collect_term_references(&self, node: Node, references: &mut Vec<TermReference>) {
        if node.kind() == "term_reference" {
            // 只有成功解析的术语引用才添加（过滤掉Markdown标题）
            if let Ok(reference) = TermReference::from_node(node, &self.source) {
                references.push(reference);
            }
        }

        for child in node.children(&mut node.walk()) {
            self.collect_term_references(child, references);
        }
    }
}

/// DPML节点包装器
#[derive(Debug, Clone)]
pub struct DpmlNode<'a> {
    node: Node<'a>,
    source: &'a str,
}

impl<'a> DpmlNode<'a> {
    pub fn new(node: Node<'a>, source: &'a str) -> Self {
        Self { node, source }
    }

    pub fn kind(&self) -> &str {
        self.node.kind()
    }

    pub fn text(&self) -> &str {
        &self.source[self.node.byte_range()]
    }

    pub fn children(&self) -> Vec<DpmlNode<'a>> {
        self.node.children(&mut self.node.walk())
            .map(|child| DpmlNode::new(child, self.source))
            .collect()
    }
}

/// DPML元素
#[derive(Debug, Clone)]
pub struct DpmlElement {
    tag_name: String,
    attributes: HashMap<String, String>,
    content: String,
    is_self_closing: bool,
}

impl DpmlElement {
    /// 从tree-sitter节点创建元素
    pub fn from_node(node: Node, source: &str) -> Result<Self> {
        let mut tag_name = String::new();
        let mut attributes = HashMap::new();
        let mut content = String::new();
        let mut is_self_closing = false;

        // 查找第一个子节点
        let first_child = node.child(0)
            .ok_or_else(|| anyhow!("Element node has no children"))?;

        match first_child.kind() {
            "self_closing_element" => {
                is_self_closing = true;

                // 提取标签名
                for child in first_child.children(&mut first_child.walk()) {
                    match child.kind() {
                        "tag_name" => {
                            // 标签名可能包含命名空间，需要获取完整文本
                            tag_name = source[child.byte_range()].to_string();
                        }
                        "attribute" => {
                            // 提取属性
                            if let (Some(name_node), Some(value_node)) =
                                (child.child(0), child.child(2)) {
                                let name = source[name_node.byte_range()].to_string();
                                let value = source[value_node.byte_range()].trim_matches('"').to_string();
                                attributes.insert(name, value);
                            }
                        }
                        _ => {}
                    }
                }
            }
            "paired_element" => {
                // 提取开始标签信息
                if let Some(start_tag) = first_child.child(0) {
                    for child in start_tag.children(&mut start_tag.walk()) {
                        match child.kind() {
                            "tag_name" => {
                                tag_name = source[child.byte_range()].to_string();
                            }
                            "attribute" => {
                                if let (Some(name_node), Some(value_node)) =
                                    (child.child(0), child.child(2)) {
                                    let name = source[name_node.byte_range()].to_string();
                                    let value = source[value_node.byte_range()].trim_matches('"').to_string();
                                    attributes.insert(name, value);
                                }
                            }
                            _ => {}
                        }
                    }
                }

                // 提取内容（除了开始和结束标签）
                let mut content_parts = Vec::new();
                for i in 1..first_child.child_count() - 1 {
                    if let Some(child) = first_child.child(i) {
                        content_parts.push(source[child.byte_range()].to_string());
                    }
                }
                content = content_parts.join("");
            }
            _ => {
                return Err(anyhow!("Unknown element type: {}", first_child.kind()));
            }
        }

        Ok(Self {
            tag_name,
            attributes,
            content,
            is_self_closing,
        })
    }

    pub fn tag_name(&self) -> &str {
        &self.tag_name
    }

    pub fn attributes(&self) -> &HashMap<String, String> {
        &self.attributes
    }

    pub fn content(&self) -> &str {
        &self.content
    }

    pub fn is_self_closing(&self) -> bool {
        self.is_self_closing
    }

    pub fn get_attribute(&self, name: &str) -> Option<&String> {
        self.attributes.get(name)
    }
}

/// 资源引用
#[derive(Debug, Clone)]
pub struct ResourceReference {
    prefix: String,
    protocol: String,
    path: String,
    query_params: HashMap<String, String>,
}

impl ResourceReference {
    pub fn from_node(node: Node, source: &str) -> Result<Self> {
        let text = &source[node.byte_range()];
        
        // 解析前缀
        let prefix = if text.starts_with("@!") {
            "@!".to_string()
        } else if text.starts_with("@?") {
            "@?".to_string()
        } else {
            "@".to_string()
        };

        // 简单解析，实际实现需要更复杂的逻辑
        let without_prefix = text.trim_start_matches(&prefix);
        let parts: Vec<&str> = without_prefix.split("://").collect();
        
        if parts.len() >= 2 {
            let protocol = parts[0].to_string();
            let path_and_query = parts[1];
            
            let (path, query_params) = if let Some(query_start) = path_and_query.find('?') {
                let path = path_and_query[..query_start].to_string();
                let query_str = &path_and_query[query_start + 1..];
                let params = Self::parse_query_params(query_str);
                (path, params)
            } else {
                (path_and_query.to_string(), HashMap::new())
            };

            Ok(Self {
                prefix,
                protocol,
                path,
                query_params,
            })
        } else {
            Err(anyhow!("Invalid resource reference format"))
        }
    }

    fn parse_query_params(query_str: &str) -> HashMap<String, String> {
        let mut params = HashMap::new();
        for param in query_str.split('&') {
            if let Some(eq_pos) = param.find('=') {
                let key = param[..eq_pos].to_string();
                let value = param[eq_pos + 1..].to_string();
                params.insert(key, value);
            }
        }
        params
    }

    pub fn prefix(&self) -> &str {
        &self.prefix
    }

    pub fn protocol(&self) -> &str {
        &self.protocol
    }

    pub fn path(&self) -> &str {
        &self.path
    }

    pub fn query_params(&self) -> &HashMap<String, String> {
        &self.query_params
    }
}

/// 术语引用
#[derive(Debug, Clone)]
pub struct TermReference {
    term: String,
}

impl TermReference {
    pub fn from_node(node: Node, source: &str) -> Result<Self> {
        let text = &source[node.byte_range()];

        // 检查是否是Markdown标题（行首的#）
        let start_byte = node.start_byte();
        let line_start = source[..start_byte].rfind('\n').map(|pos| pos + 1).unwrap_or(0);
        let before_hash = &source[line_start..start_byte];

        // 如果#前面只有空白字符，则认为是Markdown标题，跳过
        if before_hash.trim().is_empty() {
            return Err(anyhow!("Markdown heading, not a term reference"));
        }

        let term = text.trim_start_matches('#').to_string();

        Ok(Self { term })
    }

    pub fn term(&self) -> &str {
        &self.term
    }
}
